
#include "hdpvrtool.h"

// ----------------------------------------------------------------------------
// the application class
// ----------------------------------------------------------------------------

// 'Main program' equivalent: the program execution "starts" here
bool HDPVRTool::OnInit()
{
    // call the base class initialization method
    if ( !wxApp::OnInit() )
        return false;

    // create the main application window and show it
    MainFrame *frame = new MainFrame("HDPVR Tool");
    frame->Show(true);
	SetTopWindow(frame);
	frame->SetBackgroundStyle(wxBG_STYLE_CUSTOM);  // paint our own background 

    return true;
}

// ----------------------------------------------------------------------------
// main frame
// ----------------------------------------------------------------------------

// frame constructor
MainFrame::MainFrame(const wxString& title)
       : wxFrame(NULL, wxID_ANY, title)
{
    // set the frame icon
    SetIcon(wxICON(sample));

#if wxUSE_MENUS
    // create a menu bar
    contextMenu = new wxMenu;

	contextMenu->Append(ID_OpenGraph, "Open Device",  "Open HDPVR Capture Device");
	contextMenu->Append(ID_CloseGraph, "Close Device", "Close HDPVR CaptureDevice");
	contextMenu->Append(ID_StartCapture, "Play", "Start HDPVR Live Playback");
	contextMenu->Append(ID_StopCapture, "Stop", "Stop HDPVR Live Playback");
	contextMenu->Append(ID_ToggleMute, "Mute", "Mute Audio");
	contextMenu->Append(ID_ToggleFullScreen, "Full Screen", "Full Screen Toggle");
    contextMenu->Append(ID_About, "About", "Show about dialog");
    contextMenu->Append(ID_Quit, "Exit", "Quit this program");


#endif // wxUSE_MENUS

#if wxUSE_STATUSBAR
    // create a status bar just for fun (by default with 1 pane only)
    CreateStatusBar(2);
    SetStatusText("Welcome to wxWidgets!");
#endif // wxUSE_STATUSBAR

	// get window handle to pass to GraphManager
	vidWnd = HWND(this->GetHandle());

	cMan = new CodecManager();
	graphMan = new GraphManager(vidWnd, cMan);

	// set default codecs
	FilterIdent* aDec = NULL;
	FilterIdent* vDec = NULL;
	FilterIdent* xBar = NULL;
	FilterIdent* cDev = NULL;
	FilterIdent* cEnc = NULL;
	
	cMan->GetAudDecID(&aDec, MS_AUDIO);
	cMan->GetVidDecID(&vDec, MS_VIDEO);
	cMan->GetCapID(&xBar, HDPVR_CROSSBAR);
	cMan->GetCapID(&cDev, HDPVR_CAPTURE);
	cMan->GetCapID(&cEnc, HDPVR_ENCODER);

	graphMan->SetAudDec(aDec);
	graphMan->SetVidDec(vDec);
	graphMan->SetXBar(xBar);
	graphMan->SetCapDev(cDev);
	graphMan->SetEncoder(cEnc);

	isMuted = false;
}

MainFrame::~MainFrame()
{
	// clean up our pointers
	SAFE_DELETE(cMan);
	SAFE_DELETE(graphMan);

	SAFE_DELETE(contextMenu);

}


// event handlers

void MainFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
{
    // true is to force the frame to close
    Close(true);
}

void MainFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
{
    wxMessageBox(wxString::Format
                 (
                    "HDPVR Tool\n"
                    "running under %s.",
                    wxVERSION_STRING,
                    wxGetOsDescription()
                 ),
                 "About HDPVRTool",
                 wxOK | wxICON_INFORMATION,
                 this);
}

void MainFrame::PaintBackground(wxDC& dc)
{
	// paint the background ourselves, to elimnate flickering
	wxColour backgroundColour = GetBackgroundColour();
	if (!backgroundColour.Ok())
		backgroundColour =
			wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE);

	dc.SetBrush(wxBrush(backgroundColour));
	dc.SetPen(wxPen(backgroundColour, 1));

	wxRect windowRect(wxPoint(0, 0), GetClientSize());    

	dc.DrawRectangle(windowRect);
}

void MainFrame::OnPaint(wxPaintEvent& event)
{
	wxPaintDC dc(this);
	if (graphMan->HasVideo())
	{
		// paint the video if we have video
		graphMan->Repaint(::GetDC(vidWnd));
	}
	else
	{
		PaintBackground(dc);
	}
}

// empty erase event to prevent automatic background drawing
// (eliminates flickering)
void MainFrame::OnErase(wxEraseEvent& event)
{

}

void MainFrame::OnSize(wxSizeEvent& event)
{
	RECT vWinRect = GetClientWindowArea();
	graphMan->UpdateVideoWindow(&vWinRect);
}

void MainFrame::OnMove(wxMoveEvent& event)
{
	RECT vWinRect = GetClientWindowArea();
	graphMan->UpdateVideoWindow(&vWinRect);
}

void MainFrame::ShowContextMenu(wxContextMenuEvent& event)
{
	PopupMenu(contextMenu);
}

void MainFrame::OnOpen(wxCommandEvent& event)
{
	graphMan->OpenGraph();

	// update the video window size if successful
	if (graphMan->HasVideo())
	{
		RECT vWinRect = GetClientWindowArea();
		graphMan->UpdateVideoWindow(&vWinRect);
	}
}

void MainFrame::OnClose(wxCommandEvent& event)
{
	graphMan->CloseGraph();

	// refresh background
	wxClientDC dc(this);
	PaintBackground(dc);
}

void MainFrame::OnStartPlayback(wxCommandEvent& event)
{
	graphMan->Play();
}

void MainFrame::OnStopPlayback(wxCommandEvent& event)
{
	graphMan->Stop();
}

void MainFrame::OnMuteToggle(wxCommandEvent& event)
{
	isMuted = !isMuted;
	graphMan->Mute(isMuted);
}

void MainFrame::OnFullScreenToggle(wxCommandEvent& event)
{
	if (!IsFullScreen())
		ShowFullScreen(true);
	else
		ShowFullScreen(false);
}


RECT MainFrame::GetClientWindowArea()
{
	RECT tmpRect;

	// get the size (in pixels) of the window client area
	wxSize winSize = GetClientSize();

	tmpRect.top = 0;
	tmpRect.left = 0;
	tmpRect.bottom = winSize.GetHeight();
	tmpRect.right = winSize.GetWidth();

	return tmpRect;
}